home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 3: CDPD 3 / Almathera Ten on Ten - Disc 3: CDPD3.iso / scope / 051-075 / scopedisk58 / md / md.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-03-19  |  6.4 KB  |  199 lines

  1. /* MD.c
  2.  
  3.    by Fabbian G. Dufoe, III
  4.  
  5.    This is a public domain program.  Use it however you like.
  6.  
  7.    This program tests any memory which the operating system will allocate to
  8.    it.  It tests the memory one byte at a time by setting it to 0x00, the
  9.    comparing it to 0x00, setting it to 0xff, and comparing it to 0xff.  If
  10.    the comparison fails it writes the memory address (the pointer value),
  11.    the expected contents, and the actual contents of the memory location to
  12.    standard output.  Standard output may be redirected to a file if it is
  13.    desired to save the report.
  14.  
  15. */
  16.  
  17. #define NULL 0L
  18. #define SIZE 1000
  19. #define VERSION "Version 1.0, 10 January 1989\n\n"
  20.  
  21. #include <time.h>
  22. #include <stdio.h>
  23.  
  24. typedef struct
  25. {
  26.    unsigned char *ptr;
  27.    unsigned long int size;
  28. } Block;
  29.  
  30. void
  31. main()
  32. {
  33.    Block block[SIZE];
  34.    unsigned short int count = 0;
  35.    unsigned long int errct = 0;
  36.    unsigned short int high;
  37.    unsigned long int offset;
  38.    unsigned char *ptr;
  39.    unsigned long int size;
  40.    signed long int t;
  41.    static unsigned char TestVal[] = {0, 0xff, 0x55, 0xaa};
  42.    unsigned short int val;
  43.  
  44.    /* We want to include the time the diagnostic program was run in the
  45.       report.  That requires getting the current system time.
  46.    */
  47.    time(&t);
  48.  
  49.    /* We'll print a report heading and copyright notice at the beginning.
  50.    */
  51.    printf("MD--Memory Diagnostic.\n");
  52.    printf("by Fabbian G. Dufoe, III\n");
  53.    printf(VERSION);
  54.    printf("Memory tested %s\n\n", ctime(&t));
  55.  
  56.    /* We'll start by allocating memory in blocks of one megabyte.  The plan
  57.       is to allocate as many one-megabyte blocks as we can.  Then we'll
  58.       halve the block size, allocate as many blocks of that size as we can,
  59.       and repeat the process until (a) all the memory is gone or (b) we've
  60.       filled the array we allocated for keeping track of memory blocks.
  61.    */
  62.    size = 1048576;
  63.    while (size > 0 && count < SIZE)
  64.    {
  65.       fprintf(stderr, "Allocating %ld byte blocks.\n", size);
  66.       while ((ptr = (unsigned char *)malloc(size)) != NULL)
  67.       {
  68.          block[count].ptr = ptr;
  69.          block[count++].size = size;
  70.       }
  71.       if (size == 1)
  72.          size = 0;
  73.       else
  74.          size >>= 1;
  75.    }
  76.  
  77.    /* Because we expect to seldom use the entire array we've set aside we
  78.       need to save the number of the highest element actually used.
  79.    */
  80.    high = count;
  81.  
  82.    /* At this point we want to sort the block pointers.  It makes the output
  83.       easier to follow if memory errors are reported in ascending order
  84.       by their address.  We aren't guaranteed that memory will be
  85.       allocated in any particular order.  We'll use an insertion sort and
  86.       we'll sort only that part of the array we used.  That means we'll
  87.       keep the index values between 0 and high.
  88.  
  89.       An insertion sort works by shifting all the items left of the current
  90.       one right one position until an item is less than the current one.
  91.       Imagine the items to be sorted are laid out from left to right.  Then
  92.       the sort places the current item in the position vacated by the last
  93.       item to be shifted right.  The sort starts with the second item as
  94.       the current one and proceeds to the right until all the items have had
  95.       a turn as the current one.
  96.    */
  97.    fprintf(stderr, "Sorting block list.\n");
  98.    for (count = 1; count < high; count++)
  99.    {
  100.       short int i;
  101.  
  102.       ptr = block[count].ptr;
  103.       size = block[count].size;
  104.       i = count - 1;
  105.       while (i >=0 && ptr < block[i].ptr)
  106.       {
  107.          block[i+1].ptr = block[i].ptr;
  108.          block[i+1].size = block[i].size;
  109.          i--;
  110.       }
  111.       block[i+1].ptr = ptr;
  112.       block[i+1].size = size;
  113.    }
  114.    fprintf(stderr, "Sort complete.\n");
  115.  
  116.    /* We'll list the block addresses and size in the report.
  117.    */
  118.    printf("Blocks examined:\n");
  119.    printf("Block #    Address         Size\n\n");
  120.    for (count = 0; count < high; count++)
  121.    {
  122.       printf("%4d      %8lX      %7ld\n", count, block[count].ptr,
  123.              block[count].size);
  124.    }
  125.    printf("\n");
  126.  
  127.    /* Now that we've sorted our list of blocks we're ready to start testing
  128.       them.  The first step is to initialize all the variables to 0, the
  129.       first test value.
  130.    */
  131.    for (count = 0; count < high; count++)
  132.    {
  133.       fprintf(stderr, "Initializing block %d, %ld bytes.\n", count,
  134.                       block[count].size);
  135.       for (offset = 0; offset < block[count].size; offset++)
  136.          *(block[count].ptr+offset) = TestVal[0];
  137.    }
  138.  
  139.    /* Next we'll go through all the blocks to see if they contain the test
  140.       value with which they were loaded.  If not we'll identify the address
  141.       that failed, the value it contained, and the value it should have
  142.       contained.  We'll do that for each valid test value.
  143.    */
  144.    for (val = 1; val < 4; val++)
  145.    {
  146.       fprintf(stderr, "Testing value %X.\n", TestVal[val-1]);
  147.       for (count = 0; count < high; count++)
  148.       {
  149.          fprintf(stderr, "Testing block %d, %ld bytes with %X\n", count,
  150.                          block[count].size, TestVal[val-1]);
  151.          for (offset = 0; offset < block[count].size; offset++)
  152.          {
  153.             if (*(block[count].ptr+offset) != TestVal[val-1])
  154.             {
  155.                printf("ERROR! Address: %8lX  found: %2X  expected: %2X\n",
  156.                        block[count].ptr+offset, *(block[count].ptr+offset),
  157.                        TestVal[val-1]);
  158.                errct++;
  159.             }
  160.             *(block[count].ptr+offset) = TestVal[val];
  161.          }
  162.       }
  163.    }
  164.  
  165.    /* We've tested for all values except the last one.  It's time to do that
  166.       now.
  167.    */
  168.    val--;
  169.    fprintf(stderr, "Testing value %X.\n", TestVal[val]);
  170.    for (count = 0; count < high; count++)
  171.    {
  172.       fprintf(stderr, "Testing block %d, %ld bytes with %X\n", count,
  173.               block[count].size, TestVal[val]);
  174.       for (offset = 0; offset < block[count].size; offset++)
  175.       {
  176.          if (*(block[count].ptr+offset) != TestVal[val])
  177.          {
  178.             printf("ERROR! Address: %8lX  found: %2X  expected: %2X\n",
  179.                     block[count].ptr+offset, *(block[count].ptr+offset),
  180.                     TestVal[val]);
  181.             errct++;
  182.          }
  183.       }
  184.    }
  185.  
  186.    /* The testing is finished so we'll report the number of errors we found.
  187.    */
  188.    printf("\nMD found %d errors.\n", errct);
  189.  
  190.    /* When we've completed all our tests we free all the memory we allocated
  191.       and exit. */
  192.    for (count = 0; count < high; count++)
  193.    {
  194.       fprintf(stderr, "Freeing block %d.\n", count);
  195.       free(block[count].ptr);
  196.    }
  197.    exit(0);
  198. }
  199.